# -*- coding: utf-8 -*-

"""
@author: Laowang
@contact: QQ:1125564921
@Created on: 2022/7/11
@Remark: 
"""

import signal
import asyncio
import os
import sys
import logging

file_exec_path = os.path.dirname(os.path.dirname(__file__))
sys.path.insert(0, file_exec_path)

from framework_strategy.gopy import settings  # NOQA
from framework_strategy.gopy.trader.engine import MainEngine, EventEngine  # NOQA
from framework_strategy.gopy.gateways.object import *  # NOQA
from framework_strategy.gopy.gateways.xt.v3.spot.xt_api import XTGateway  # NOQA
from framework_strategy.gopy.gateways.xt.v3.future.xt_future_api import XTFUTUREGateway  # NOQA
from framework_strategy.gopy.gateways.binance.binance_api import BINANCEGateway  # NOQA
from framework_strategy.gopy.gateways.ftx.ftx_api import FTXGateway  # NOQA
from framework_strategy.gopy.gateways.rpc import RPCManager  # NOQA

# LOAD ENV
if not os.environ.get("FRAMEWORK_STRATEGY"):
    os.environ["FRAMEWORK_STRATEGY"] = settings.FRAMEWORK_STRATEGY

def _except_record(msg):
    logging.error(msg)

# track


def strategy_excepthook(exc_type, exc_value, traceback):
    msg = ' Traceback (most recent call last):\n'
    while traceback:
        filename = traceback.tb_frame.f_code.co_filename
        name = traceback.tb_frame.f_code.co_name
        lineno = traceback.tb_lineno
        msg += ' File "%.500s", line %d, in %.500s\n' % (
            filename, lineno, name)
        traceback = traceback.tb_next
        msg += ' %s: %s\n' % (exc_type.__name__, exc_value)
        _except_record(msg)


async def create_app():
    """ """
    killer = GracefulKiller()

    event_engine = EventEngine()
    main_engine = MainEngine(event_engine)

    # Base-Gateway
    main_engine.add_gateway(XTGateway)
    main_engine.add_gateway(BINANCEGateway)
    main_engine.add_gateway(XTFUTUREGateway)

    # Gate-Manager
    main_engine.add_gateway(FTXGateway)
    main_engine.add_gateway(RPCManager)

    while 1:
        if killer.kill_now:
            break
        await asyncio.sleep(2)
        # print("[manager] running .....")
    main_engine.close()


class GracefulKiller:
    kill_now = False

    def __init__(self):
        signal.signal(signal.SIGINT, self.exit_gracefully)
        signal.signal(signal.SIGTERM, self.exit_gracefully)

    def exit_gracefully(self, signum, frame):
        self.kill_now = True


def start():
    #
    sys.excepthook = strategy_excepthook

    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(create_app())
    finally:
        # see: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.shutdown_asyncgens
        loop.run_until_complete(loop.shutdown_asyncgens())
        loop.close()


if __name__ == "__main__":
    # python .\framework_strategy\manager.py
    #
    start()
